from typing import List, Optional, Dict
from uuid import UUID
from sqlalchemy.ext.asyncio import AsyncSession

from crud.document import document_category as category_crud
from schemas.document.document_category import DocumentCategoryCreate, DocumentCategoryUpdate, DocumentCategoryTreeResponse, DocumentCategoryResponse
from log import log_info, log_error


# 系统预设分类数据
SYSTEM_CATEGORIES = [
    {"name": "法律法规", "icon": "⚖️", "color": "#dc3545", "description": "相关法律法规文档", "is_system": True},
    {"name": "行业标准", "icon": "📊", "color": "#28a745", "description": "行业标准和规范文档", "is_system": True},
    {"name": "内部制度", "icon": "📄", "color": "#007bff", "description": "公司内部制度文档", "is_system": True},
    {"name": "技术规范", "icon": "⚙️", "color": "#6f42c1", "description": "技术规范和标准文档", "is_system": True},
    {"name": "操作手册", "icon": "📖", "color": "#fd7e14", "description": "操作手册和指南文档", "is_system": True},
]


async def initialize_system_categories(db: AsyncSession) -> None:
    """初始化系统预设分类"""
    try:
        log_info("开始初始化系统预设分类", module="core.document_category")
        
        # 检查是否已经初始化过
        existing_categories = await category_crud.get_all_categories(db)
        if existing_categories:
            log_info("系统分类已存在，跳过初始化", module="core.document_category")
            return
        
        # 创建系统预设分类
        for category_data in SYSTEM_CATEGORIES:
            category = DocumentCategoryCreate(**category_data)
            await category_crud.create_category(db, category)
            log_info(f"创建系统分类: {category_data['name']}", module="core.document_category")
        
        log_info("系统预设分类初始化完成", module="core.document_category")
        
    except Exception as e:
        log_error(f"初始化系统分类失败: {str(e)}", exc_info=True, module="core.document_category")
        raise


async def get_category_tree(db: AsyncSession) -> List[DocumentCategoryTreeResponse]:
    """获取分类树结构"""
    try:
        log_info("获取分类树结构", module="core.document_category")
        
        # 获取所有分类及其文档数量
        categories_with_count = await category_crud.get_categories_with_document_count(db)
        
        # 构建分类字典，便于查找
        category_dict = {}
        for category, document_count in categories_with_count:
            category_response = DocumentCategoryTreeResponse(
                id=category.id,
                name=category.name,
                icon=category.icon,
                color=category.color,
                description=category.description,
                parent_id=category.parent_id,
                sort_order=category.sort_order,
                is_system=category.is_system,
                document_count=document_count,
                created_at=category.created_at,
                updated_at=category.updated_at,
                children=[]
            )
            category_dict[category.id] = category_response
        
        # 构建树形结构
        root_categories = []
        for category_id, category in category_dict.items():
            if category.parent_id is None:
                root_categories.append(category)
            else:
                parent = category_dict.get(category.parent_id)
                if parent:
                    parent.children.append(category)
        
        # 排序
        def sort_categories(categories):
            categories.sort(key=lambda x: (x.sort_order, x.name))
            for category in categories:
                sort_categories(category.children)
        
        sort_categories(root_categories)
        
        log_info(f"获取到 {len(root_categories)} 个根分类", module="core.document_category")
        return root_categories
        
    except Exception as e:
        log_error(f"获取分类树失败: {str(e)}", exc_info=True, module="core.document_category")
        raise


async def create_category(db: AsyncSession, category: DocumentCategoryCreate) -> DocumentCategoryResponse:
    """创建新分类"""
    try:
        log_info(f"创建新分类: {category.name}", module="core.document_category")
        
        # 验证父分类是否存在
        if category.parent_id:
            parent_category = await category_crud.get_category_by_id(db, category.parent_id)
            if not parent_category:
                raise ValueError("父分类不存在")
        
        # 创建分类
        db_category = await category_crud.create_category(db, category)
        
        log_info(f"成功创建分类: {db_category.name} (ID: {db_category.id})", module="core.document_category")
        return db_category
        
    except Exception as e:
        log_error(f"创建分类失败: {str(e)}", exc_info=True, module="core.document_category")
        raise


async def update_category(db: AsyncSession, category_id: UUID, category: DocumentCategoryUpdate) -> Optional[DocumentCategoryResponse]:
    """更新分类信息"""
    try:
        log_info(f"更新分类: {category_id}", module="core.document_category")
        
        # 检查分类是否存在
        existing_category = await category_crud.get_category_by_id(db, category_id)
        if not existing_category:
            log_error(f"分类不存在: {category_id}", module="core.document_category")
            return None
        
        # 验证父分类（如果有更新）
        if category.parent_id is not None:
            if category.parent_id == category_id:
                raise ValueError("分类不能设置自己为父分类")
            
            if category.parent_id:
                parent_category = await category_crud.get_category_by_id(db, category.parent_id)
                if not parent_category:
                    raise ValueError("父分类不存在")
        
        # 更新分类
        updated_category = await category_crud.update_category(db, category_id, category)
        
        if updated_category:
            log_info(f"成功更新分类: {updated_category.name}", module="core.document_category")
        
        return updated_category
        
    except Exception as e:
        log_error(f"更新分类失败: {str(e)}", exc_info=True, module="core.document_category")
        raise


async def delete_category(db: AsyncSession, category_id: UUID, move_to_category_id: Optional[UUID] = None) -> bool:
    """删除分类（可指定文档迁移目标分类）"""
    try:
        log_info(f"删除分类: {category_id}, 迁移目标: {move_to_category_id}", module="core.document_category")
        
        # 检查分类是否存在
        category = await category_crud.get_category_by_id(db, category_id)
        if not category:
            log_error(f"分类不存在: {category_id}", module="core.document_category")
            return False
        
        # 检查是否为系统分类
        if category.is_system:
            raise ValueError("不能删除系统预设分类")
        
        # 检查是否有子分类
        has_children = await category_crud.check_category_has_children(db, category_id)
        if has_children:
            raise ValueError("不能删除包含子分类的分类，请先删除或移动子分类")
        
        # 验证迁移目标分类
        if move_to_category_id:
            target_category = await category_crud.get_category_by_id(db, move_to_category_id)
            if not target_category:
                raise ValueError("迁移目标分类不存在")
        
        # 迁移文档
        moved_count = await category_crud.move_documents_to_category(db, category_id, move_to_category_id)
        if moved_count > 0:
            log_info(f"迁移了 {moved_count} 个文档", module="core.document_category")
        
        # 删除分类
        success = await category_crud.delete_category(db, category_id)
        
        if success:
            log_info(f"成功删除分类: {category.name}", module="core.document_category")
        
        return success
        
    except Exception as e:
        log_error(f"删除分类失败: {str(e)}", exc_info=True, module="core.document_category")
        raise


async def get_category_statistics(db: AsyncSession) -> Dict[str, int]:
    """获取分类统计信息"""
    try:
        log_info("获取分类统计信息", module="core.document_category")
        
        categories_with_count = await category_crud.get_categories_with_document_count(db)
        
        total_categories = len(categories_with_count)
        total_documents = sum(count for _, count in categories_with_count)
        system_categories = sum(1 for category, _ in categories_with_count if category.is_system)
        custom_categories = total_categories - system_categories
        
        statistics = {
            "total_categories": total_categories,
            "system_categories": system_categories,
            "custom_categories": custom_categories,
            "total_documents": total_documents,
        }
        
        log_info(f"分类统计: {statistics}", module="core.document_category")
        return statistics
        
    except Exception as e:
        log_error(f"获取分类统计失败: {str(e)}", exc_info=True, module="core.document_category")
        raise
